#include <cstdio>
#include <iostream>
#include <cstring>
#include <string>
#include <cassert>

#define CRLF "\r\n"
#define CRLF_LEN strlen(CRLF)
#define SPACE " "
#define SPACE_LEN strlen(SPACE)
#define OPS "+-*/%"

//解码 9\r\n100 + 200\r\n    9\r\n112 / 200\r\n
static std::string decode(std::string &in, uint32_t *len) 
{
    assert(len);
    // 1. 确认是否是一个包含len的有效字符串
    *len = 0;
    std::size_t pos = in.find(CRLF); // 报头长度
    if (pos == std::string::npos)
    {
        return "";
    }
    // 2. 提取长度
    std::string inLen = in.substr(0, pos);
    int intLen = atoi(inLen.c_str()); // 报头值
    // 3. 确认有效载荷也是符合要求的
    int surplus = in.size() - (pos + CRLF_LEN * 2);
    if (surplus < intLen)
    {
        return "";
    }
    // 4. 确认有完整的报文结构
    *len = intLen;
    std::string package = in.substr(pos + CRLF_LEN, intLen);
    // 5. 将当前报文完整的从in中全部移除掉
    int removeLen = pos + CRLF_LEN * 2 + intLen;
    in.erase(0, removeLen);
    // 6. 正常返回
    return package;
}
//加码 
static std::string encode(std::string &in,size_t len) 
{
    std::string encodein=std::to_string(len);
    encodein+=CRLF;
    encodein+=in;
    encodein+=CRLF;
    return encodein;
}

// 9\r\n100 + 200\r\n    9\r\n112 / 200\r\n
class Request
{
public:
    // 反序列化 100 + 200 字符串 转 结构体
    bool deserialize(std::string &in)
    {
        size_t SpaceOne=in.find(SPACE);
        if(SpaceOne==std::string::npos)
            return false;
        size_t SpaceTwo=in.rfind(SPACE);
        if(SpaceTwo==std::string::npos)
            return false;
        x_=atoi((in.substr(0,SpaceOne)).c_str());
        y_=atoi((in.substr(SpaceTwo+SPACE_LEN)).c_str());
        std::string oper=in.substr(SpaceOne+SPACE_LEN,SpaceTwo-SpaceOne-SPACE_LEN);
        if(oper.size()!=1)
            return false;
        op_=oper[0];
        return true;
    }
    //序列化， 结构体 转 字符串 "1 + 1"
    void serialize(std::string& out)
    {   
        out+=std::to_string(x_);
        out+=SPACE;
        out+=op_;
        out+=SPACE;
        out+=std::to_string(y_);
        std::cout<<"out: "<<out<<std::endl;
    }
    void debug()
    {
        std::cout << "#################################" << std::endl;
        std::cout << "x_: " << x_ << std::endl;
        std::cout << "op_: " << op_ << std::endl;
        std::cout << "y_: " << y_ << std::endl;
        std::cout << "#################################" << std::endl;
    }
    // private:
    int x_;
    int y_;
    char op_;
};

class Respond
{
public:
    Respond():exitCode_(0),result_(0)
    {}
    //序列化， 结构体 转 字符串 res.serialize(&respPackage);
    void serialize(std::string* out)
    {
        *out=std::to_string(exitCode_);
        *out+=SPACE;
        *out+=std::to_string(result_);
    }
    bool deserialize(std::string& in)
    {
        size_t pos=in.find(SPACE);
        if(pos==std::string::npos)
            return false;
        exitCode_=atoi((in.substr(0,pos)).c_str());
        result_=atoi((in.substr(pos+1)).c_str());
        return true;
    }
    int exitCode_;
    int result_;
};

//1+1 strtmp 
bool makeRequest(std::string& str,Request* req)
{
    char strtmp[1024];
    snprintf(strtmp,sizeof(strtmp)-1,"%s",str.c_str());
    char* left=strtok(strtmp,OPS);
    if(left==nullptr) return false;
    char* right=strtok(nullptr,OPS);
    if(right==nullptr) return false;
    req->x_=atoi(left);
    req->y_=atoi(right);
    req->op_=str[strlen(left)];
    return true;
}